package com.ebelter.btlibrary.btble.ble.bluetooth.device;


import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.text.TextUtils;

import com.ebelter.btlibrary.btble.ble.bluetooth.callback.BleSatusCallback;
import com.ebelter.btlibrary.btble.ble.bluetooth.callback.ConnectCallback;
import com.ebelter.btlibrary.btble.ble.bluetooth.callback.ScanResultCallback;
import com.ebelter.btlibrary.btble.ble.bluetooth.device.impl.BleMessageAnalyser;
import com.ebelter.btlibrary.btble.ble.bluetooth.device.impl.Channel;
import com.ebelter.btlibrary.btble.ble.model.BleDevice;
import com.ebelter.btlibrary.btble.ble.model.BleType;
import com.ebelter.btlibrary.btble.common.Fields;
import com.ebelter.btlibrary.helper.BtThreadPool;
import com.ebelter.btlibrary.util.SpUtil;
import com.ebelter.btlibrary.util.ULog;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 蓝牙数据传输服务
 *
 * @author fenghui
 */
@SuppressLint("NewApi")
public class BlueToothServer implements IBleServerWriter {
    private static String TAG = "BlueToothServer";        //tag
    protected Context mContext;                                    //context
    public boolean mScanning = false;                           //是否扫描
    protected boolean isScanningRunning = false;                   //
    protected boolean isConnected = false;                        //是否已连接
    protected boolean isNeedConnecting = false;
    protected int scanTimeout = BluetoothUtil.getScanTimeout();    //扫描超时时间
    protected int connectTotal = 0;
    static String blueToothMac = "";

    static BluetoothAdapter mBluetoothAdapter;                //adapter
    protected int currDeviceType = -1;                        //当前测量设备类型
    protected BluetoothDevice currConnectDevice = null;        //当前连接设备
    protected int lastRssi = 0;                                //标记变量，用于记录上一次扫描到的设备的rssi信号
    protected BluetoothGatt mBluetoothGatt;
    protected long currMutualTime = 0;                        //当前数据交互时间
    //    protected AbstractDeviceDataHandle deviceDataHandler;    //数据处理
    protected String[] deviceReadNotifyUUIDs = null;        //蓝牙设备监听端口
    protected BluetoothGattService btService = null;
    static BlueToothServer instance = null;
    protected int deviceConnectState = BluetoothProfile.STATE_DISCONNECTED;
    protected boolean isListeneredBleState = false;
    protected boolean healthScanDeviced = false;
    protected boolean isOpenBluetoothing = false;
    protected HandlerThread handlerThread;
    protected Handler mHandler;
    private OnDeviceConnectedListener mConnectedListener;
    private BleSatusCallback mBleSatusCallback;
    protected ScanResultCallback mScanResultCallback;
    protected ConnectCallback mConnectCallback;
    protected BleMessageAnalyser mBleMessageAnalyser;
    /***** 是否多蓝牙 ****/
    protected boolean isMutiBle = false;


    protected BlueToothServer(Context ctx) {
        this.mContext = ctx;
//        this.deviceDataHandler = deviceDataHandler;

        //init handler
        handlerThread = new HandlerThread(TAG);
        handlerThread.start();
        mHandler = new Handler(handlerThread.getLooper());
    }

    public static BlueToothServer getInstance(Context ctx) {
        if (instance == null) {

            BluetoothUtil.ConnectType mConnectType = BluetoothUtil.getConnectType();
            switch (mConnectType) {
                case GATT_AUTO_FALSE:
                    ULog.i(TAG,"getInstance()--mConnectType是---GATT_AUTO_FALSE--BlueToothServer");
                    instance = new BlueToothServer(ctx);
                    break;
                case GATT_AUTO_TRUE:
                    ULog.i(TAG,"getInstance()--mConnectType是---GATT_AUTO_TRUE--BtAutoGattListener");
                    instance = new BtAutoGattListener(ctx);
                    break;
                case SCAN_BLE_LOLLIPOP:
                    ULog.i(TAG,"getInstance()--mConnectType是---SCAN_BLE_LOLLIPOP--BtScanLollipopListener");
                    instance = new BtScanLollipopListener(ctx);//里面采用的是蓝牙5.0的扫描方式
                    break;
                case SCAN_BLE_LOLLIPOP_GATT_AUTO_TRUE:
                    ULog.i(TAG,"getInstance()--mConnectType是---SCAN_BLE_LOLLIPOP_GATT_AUTO_TRUE--BtScanLollipopAndAutoGattListener");
                    instance = new BtScanLollipopAndAutoGattListener(ctx);
                    break;
                default:
                    ULog.i(TAG,"getInstance()--mConnectType是---default--BlueToothServer");
                    instance = new BlueToothServer(ctx);
                    break;
            }


            // 初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上和版本)
//	        BluetoothManager bluetoothManager = (BluetoothManager) ctx.getSystemService(Context.BLUETOOTH_SERVICE);
//	        mBluetoothAdapter = bluetoothManager.getAdapter();

            //读取绑定的设备的mac
//            SharePrefrenceHelper spf = new SharePrefrenceHelper(ctx);
//            spf.open(FileNames.STRING_FILE);
//            OnDeviceBindFoundListener.mac = spf.getString(Fields.DEVICE_MAC);

            OnDeviceBindFoundListener.mac = SpUtil.readString(Fields.DEVICE_MAC,null);

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();



            if (mBluetoothAdapter != null) {
                blueToothMac = mBluetoothAdapter.getAddress();
            }

            instance.setListenerBluetoothState(true);
        }
        return instance;
    }

    public void registerScanResultCallback(ScanResultCallback callback) {
        this.mScanResultCallback = callback;
    }

    public void registerConnectCallback(ConnectCallback callback) {
        this.mConnectCallback = callback;
    }

    public void registerBleMessageAnalyser(BleMessageAnalyser messageAnalyser) {
        this.mBleMessageAnalyser = messageAnalyser;
    }


    /**
     * 开始扫描蓝牙设备
     */
    public int startScanDevice() {
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            ULog.e(TAG, "startScanDevice error. bluetoothAdapter not enabled.");
            return 0;
        }

        ULog.i(TAG, "startScanDevice. isScanningRunning:" + isScanningRunning);

        // 检查当前手机是否支持ble 蓝牙,如果不支持退出程序
        if (!isScanningRunning) {
            if (deviceConnectState == BluetoothProfile.STATE_DISCONNECTED) {
                isScanningRunning = true;
                if (mHandler != null) {
                    mHandler.removeCallbacks(scanningThread);
                    mHandler.post(scanningThread);
                }
            } else {
                ULog.e(TAG, "is already connected devices.don't do scan operate.");
            }
        } else {
            ULog.e(TAG, "is already scan devices.don't scan again.");
        }

        return BluetoothUtil.START_DEVICE_CODE_SUCCESS;
    }

    /**
     * 停止扫描蓝牙设备
     */
    public void stopScanDevice() {
        ULog.i(TAG, "----stopScanDevice-----do stop scan device.");
        isScanningRunning = false;
        scanLeDevice(false);
        if (mHandler != null) {
            mHandler.removeCallbacks(scanningThread);
            mHandler.removeCallbacksAndMessages(null);
        }
    }

    /**
     * 获取连接状态
     *
     * @return
     */
    public boolean getConnectState() {
        //未打开的时候，请求打开
        if (!mBluetoothAdapter.isEnabled()) {
            if (mHandler != null) {
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (!isOpenBluetoothing) {
                            mBluetoothAdapter.enable();
                        }
                    }
                }, 500);
            }
        }
        return isConnected;
    }

    /**
     * 获取当前手机蓝牙mac地址
     *
     * @return
     */
    public String getTelBlueToothMac() {
        return blueToothMac;
    }

    /***
     * 获取连接设备mac地址
     */
    public String getConnectDeviceMac() {
        if (currConnectDevice != null) {
            return currConnectDevice.getAddress();
        }
        return "";
    }

    public void reConnect(){
        if (currConnectDevice!=null){
            startConnectDevice(currConnectDevice);
        }
    }
    /**
     * 开始连接设备
     */
    public void startConnectDevice(BluetoothDevice device) {
        ULog.i(TAG, "do startConnectDevice. isConnected:" + isConnected);

        //isNeedConnecting = true; zcq于201804201722删除掉


        currConnectDevice = device;
//        deviceDataHandler.setDeviceAddress(device.getAddress());
        if (!isConnected&&currConnectDevice!=null) {
            if (mHandler != null) {
                mHandler.removeCallbacks(connectTimeoutThread);
                mHandler.postDelayed(connectTimeoutThread, BluetoothUtil.getConnectTimeout());
            }
            deviceConnectState = BluetoothProfile.STATE_CONNECTING;
            if (mBluetoothGatt==null){
                ULog.i(TAG,"-----currConnectDevice.connectGatt之--前:mBluetoothGatt =----空" );
            }else {
                ULog.i(TAG,"-----currConnectDevice.connectGatt之--前:mBluetoothGatt =--不为空" );
            }

            mBluetoothGatt = currConnectDevice.connectGatt(mContext, false, mGattCallback);

            if (mBluetoothGatt==null){
                ULog.i(TAG,"-----currConnectDevice.connectGatt之--后:mBluetoothGatt =----空" );
            }else {
                ULog.i(TAG,"-----currConnectDevice.connectGatt之--后:mBluetoothGatt =--不为空" );
            }

            refreshDeviceCache(mBluetoothGatt);
        }
    }

    public void startConnectDevice(String deviceAddress){
        ULog.i(TAG,TAG+"--startConnectDevice()--deviceAddress = "+deviceAddress);
        try {
            BluetoothDevice device=mBluetoothAdapter.getRemoteDevice(deviceAddress);
            startConnectDevice(device);
        }catch (Exception e){
            e.printStackTrace();
            ULog.i(TAG,TAG+"---出现异常---startConnectDevice()--deviceAddress = "+deviceAddress);
        }

    }


    /**
     * 断开蓝牙连接
     */
    public void disConnectDevice() {

        stopScanDevice();

        isNeedConnecting = false;
        isConnected = false;
        connectTotal = 0;
        //TODO 需实现该方法
//        deviceDataHandler.sendDisconnectBt();
        //disabledServiceDestript();
        deviceConnectState = BluetoothProfile.STATE_DISCONNECTED;
        if (mBluetoothGatt != null) {
            ULog.i(TAG, "-----disConnectDevice--------mBluetoothGatt.disconnect()");
            mBluetoothGatt.disconnect();
            mBluetoothGatt.close();
            mBluetoothGatt=null;
        }

        if (mConnectCallback != null) {
            mConnectCallback.onDisConnected();
        }
        currConnectDevice=null;

    }

    /**
     * 解绑设备
     */
    public void unbindDevice() {
        disConnectDevice();
        //解绑蓝牙设备
        OnDeviceBindFoundListener.mac = null;

    }

    /**
     * 重启手机蓝牙
     */
    public void restartBluetooth() {
        if (mBluetoothAdapter != null) {
            ULog.i(TAG, "do restartBluetooth.");

            mBluetoothAdapter.disable();

            BtThreadPool.addFixedThreadPoll(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
                            mBluetoothAdapter.enable();
                            break;
                        }
                    }
                }
            });
        }
    }

    /**
     * 获取蓝牙是否打开状态
     */
    public boolean getLeDevicEnabled() {
        if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
            return true;
        }
        return false;
    }

    //扫描设备
    protected void scanLeDevice(boolean enable) {

        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            ULog.e(TAG, "mBluetoothAdapter is null, or mBluetoothAdapter is not ebabled.");
            return;
        }
        ULog.i(TAG, "------scanLeDevice--------- enable = " + enable);
        if (enable) {
            ULog.d(TAG, "begin to scan bluetooth devices...");
            mScanning = true;
            try {
                mBluetoothAdapter.startLeScan(mLeScanCallback);
            } catch (Exception e) {
                ULog.e(TAG, "startLeScan error." + e.getMessage());
            }
        } else {
            ULog.d(TAG, "stop to scan bluetooth devices.");
            mScanning = false;
            try {
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
            } catch (Exception e) {
                ULog.e(TAG, "stopLeScan error." + e.getMessage());
            }
        }
    }

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        private long lastScanTime = 0;
        private String lastDeviceMac = "";

        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            ULog.i(TAG, "--------------onLeScan---------------name = " + device.getName() + ",address = " + device.getAddress() + " rssi=" + rssi);

            String name = device.getName();

            currDeviceType = BluetoothUtil.getDeviceTypeByDeviceName(name);
            ULog.i(TAG, "--------------onLeScan---------------name = " + device.getName() + ", currDeviceType = " + currDeviceType);
            if (currDeviceType > -1) {
                //TODO，停止继续扫描设备，该操作应该在匹配app绑定的mac地址后停止扫描
                //stopScanDevice();
                //只有未连接的时候才继续
                if (deviceConnectState != BluetoothProfile.STATE_DISCONNECTED) {
                    ULog.e(TAG, "deviceConnectState is：" + deviceConnectState);
                    return;
                }

                if (lastDeviceMac.equals(name)
                        && System.currentTimeMillis() - lastScanTime < 1000) {
                    ULog.i(TAG, "scan same device. address:" + lastDeviceMac);
                    lastDeviceMac = device.getAddress();
                    lastScanTime = System.currentTimeMillis();
                    return;
                }

                lastDeviceMac = device.getAddress();
                lastScanTime = System.currentTimeMillis();
                //这里首先校验当前扫描到的设备信号强度是否大于已经扫描到的设备信号强度
                lastRssi = rssi;
                //currConnectDevice = device;
                ULog.i(TAG, "found target device!");
                //通知发现设备
                if (mScanResultCallback != null) {
                    mScanResultCallback.onDiscovered(device);
                }
            }
        }
    };


    //连接回调信息
    protected BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (mHandler != null) {
                mHandler.removeCallbacks(connectTimeoutThread);
            }
            ULog.w(TAG, "--------------onConnectionStateChange---------------status = " + status + ",new status:" + newState);
            deviceConnectState = newState;

            //BluetoothGatt.GATT_SUCCESS = 0
            //BluetoothProfile.STATE_CONNECTED = 2

            if (status == BluetoothGatt.GATT_SUCCESS) {

                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    try {
                        Thread.sleep(600);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ULog.i(TAG, "start to discoverServices.--A");

                    if (mBluetoothGatt!=null){
                        ULog.i(TAG, "------------mBluetoothGatt.discoverServices()");
                        mBluetoothGatt.discoverServices();
                    }
                    ULog.i(TAG, "--mBluetoothGatt的地址："+mBluetoothGatt+"----gatt的地址"+gatt);
                    ULog.i(TAG, "start to discoverServices.---B");
                    BluetoothDevice device = gatt.getDevice();
                    if (device!=null){
                        ULog.i(TAG, "start to discoverServices.---C----device.getName="+device.getName()+"--device.getAddress="+device.getAddress());
                    }

                    //连接成功回调
                    if (mConnectedListener != null) {
                        ULog.i(TAG, "--mConnectedListener--监听器不为null");
                        mConnectedListener.onDeviceConnected(device);
                    }else {
                        ULog.i(TAG, "--mConnectedListener--为空,无法回调给前台----");
                    }


                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    //停止心跳
                    //TODO 需实现该方法
//                    ((WeightDataHandle) deviceDataHandler).stopConnHeartbeat();
                    ULog.i(TAG, "mBluetoothGatt.close()");
                    gatt.disconnect();//zcq
                    gatt.close();
                    if (isConnected) {
                        ULog.i(TAG, "device disconnected.");
                        isConnected = false;
                        lastRssi = 0;
                        if (mConnectCallback != null) {
                            mConnectCallback.onDisConnected();
//                            deviceDataHandler.getMsgCallBack().onDisConnected();
                        }
                    }
//                    if (currConnectDevice!=null){//zcq
//                        startConnectDevice(currConnectDevice);//重新连接的意思
//                    }
                    if (isNeedConnecting) {
                        startScanDevice();
                    }
                }
            } else {
                ULog.e(TAG, "status is not 0. do close operate.");
                gatt.disconnect();//zcq
                gatt.close();
                //停止心跳
                //TODO 需实现该方法
//                ((WeightDataHandle) deviceDataHandler).stopConnHeartbeat();
                mBluetoothGatt = null;
                isConnected = false;
                if (isNeedConnecting) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    startScanDevice();
                }
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            ULog.w(TAG, "--------------onServicesDiscovered---------------status = " + status);
            if (status == BluetoothGatt.GATT_SUCCESS) {

                //搜寻设备完毕，写入数据特征到设备中
                if (mBluetoothAdapter == null) {
                    ULog.e(TAG, "BluetoothAdapter not initialized");
                    return;
                }

                //打印出当前设备的services列表
                List<BluetoothGattService> gattServices = gatt.getServices();
                for (BluetoothGattService service : gattServices) {
                    ULog.i(TAG, "-----onServicesDiscovered-------service uuid:" + service.getUuid().toString());
                }

                btService = gatt.getService(UUID.fromString(BluetoothUtil.getDeviceServiceUUID()));
                if (btService == null) {
                    ULog.e(TAG, "service is null.");
                    //状态码出错，先断开连接然后再重新连接
                    isConnected = false;
                    gatt.disconnect();
                    gatt.close();
                    return;
                }

                isConnected = true;


                List<BluetoothGattCharacteristic> characteristics = btService.getCharacteristics();
                for (BluetoothGattCharacteristic characteristic : characteristics) {
                    ULog.i(TAG, "-----onServicesDiscovered-------characteristic uuid:" + characteristic.getUuid().toString());
                    setCharacteristicNotification(characteristic,true);
                }
                //数据通知uuid列表
                deviceReadNotifyUUIDs = BluetoothUtil.getReadUUIDs();

                BluetoothGattCharacteristic characteristic = btService.getCharacteristic(UUID.fromString(deviceReadNotifyUUIDs[0]));
                if (characteristic != null) {

                    //这里通知前端，设备连接成功
                    if (mConnectCallback != null) {  //zcq1805071114
                        mConnectCallback.onConnected(gatt.getDevice());
                    }
                    setCharacteristicNotification(characteristic, true);

                }


            } else {
                ULog.w(TAG, "onServicesDiscovered received: " + status);
            }
        }


        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor gattDescriptor, int status) {
            ULog.w(TAG, "--------------onDescriptorWrite---------------status = " + status);
            if (status != 0) {
                ULog.i(TAG, "onDescriptorWrite, status not 0, do disconnect.");
                //状态码出错，先断开连接然后再重新连接
                gatt.disconnect();
            } else {
                //这里通知前端，设备连接成功
                if (mConnectCallback != null) {  //zcq1805071114
                    mConnectCallback.onConnected(gatt.getDevice());
                }

                connectTotal++;
                ULog.i(TAG, "device connected times." + connectTotal
                        + ",isConnected:" + isConnected);


                //0000180a-0000-1000-8000-00805f9b34fb
                //00002a26-0000-1000-8000-00805f9b34fb

                UUID uuid = gattDescriptor.getCharacteristic().getUuid();
                ULog.i(TAG, "-----onDescriptorWrite------UUID = " + uuid+", deviceReadNotifyUUIDs.length = "+ deviceReadNotifyUUIDs.length);

                //设置多通道通知
                setMutiNotify(uuid, 1);
                setMutiNotify(uuid, 2);
                setMutiNotify(uuid, 3);

                if (BleDevice.getInstance().getType() == BleType.OXIMETER) {
                    //血氧仪，监听4个通道通知，第4通道写入数据，开始接收通知
                    if (uuid.equals(UUID.fromString(deviceReadNotifyUUIDs[3]))) {
                        ULog.i(TAG, "-----onDescriptorWrite---characteristic_4----write data ");
                        //  broadcastUpdate(BleAction.ACTION_XUEYANG_WRITE);
                        byte[] bytes = {(byte) 0xaa, 0x55, 0x04, (byte) 0xb1, 0x00, 0x00, (byte) 0xb5};
                        writeLlsAlertLevel(bytes);
                    }
                }

                //查询蓝牙固件版本信息
                if (BleDevice.getInstance().getType() == BleType.SCALE) {
                    BluetoothGattService deviceInfomaction = gatt.getService(UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb"));
                    BluetoothGattCharacteristic bleFirmwareCharacteristic = deviceInfomaction.getCharacteristic(UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb"));
                    mBluetoothGatt.readCharacteristic(bleFirmwareCharacteristic);
                    //TODO 发送心跳包
//                ((WeightDataHandle) deviceDataHandler).startConnHeartbeat();
                }
            }

        }


        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            //读取到数据
            ULog.w(TAG, "--------------onCharacteristicRead---------------status = " + status);


            if (status == BluetoothGatt.GATT_SUCCESS) {
                if(characteristic==null){
                    return;
                }
                if (characteristic.getUuid().toString().equals("00002a26-0000-1000-8000-00805f9b34fb")) {
                    //蓝牙固件版本号

                    String bleFirmwareVer = new String(characteristic.getValue());
                    ULog.i(TAG, "bleFirmwareVer is : " + bleFirmwareVer);
                    bleFirmwareVer = bleFirmwareVer.replaceAll("\\.", "");
                    // 蓝牙版本
//                    Scale.getInstance().setBleVersion(Integer.parseInt(bleFirmwareVer));
                }

               // ULog.i(TAG, "----onCharacteristicRead---characteristic UUID :" + characteristic.getUuid().toString() + ", value = " + characteristic.getValue());

                if (mBleMessageAnalyser != null) {
                    onReceiveBleMessage(characteristic.getUuid().toString(), characteristic.getValue());
                }

            }

        }

        /**
         * 返回数据。
         */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            currMutualTime = System.currentTimeMillis();
            ULog.w("--------onCharacteristicChanged---------", "isConnected:" + isConnected);
            if (!isConnected) {
                ULog.e(TAG, "device not connected, return from onCharacteristicChanged.");
                return;
            }
            ULog.i(TAG, "----onCharacteristicChanged---characteristic UUID :" + characteristic.getUuid().toString() + "\n, value = " + Arrays.toString(characteristic.getValue()));


            byte[] value = characteristic.getValue();
            if (value != null) {
                onReceiveBleMessage(characteristic.getUuid().toString(), value);
            }
        }
    };

    protected void setMutiNotify(UUID uuid, int channelNumber) {
        if (deviceReadNotifyUUIDs.length > channelNumber) {
            if (uuid.toString().equals(deviceReadNotifyUUIDs[channelNumber - 1])) {
                ULog.i(TAG, "-----onDescriptorWrite---characteristic " + (channelNumber - 1) + "----set notifty characteristic " + channelNumber);
                BluetoothGattCharacteristic characteristic = btService.getCharacteristic(UUID.fromString(deviceReadNotifyUUIDs[channelNumber]));
                if (characteristic != null) {
                    setCharacteristicNotification(characteristic, true);
                }
            }
        }
    }


    private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enable) {
        mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(BluetoothUtil.CLIENT_CHARACTERISTIC_CONFIG));
        if (descriptor != null) {
            ULog.i(TAG, "mBluetoothGatt.writeDescriptor.");
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBluetoothGatt.writeDescriptor(descriptor);
        }
    }

    protected StringBuilder dataSb;

    protected void onReceiveBleMessage(String uuid, byte[] value) {
        // 数据
        if (dataSb == null) {
            dataSb = new StringBuilder();
        } else {
            dataSb.setLength(0);
        }

        for (int i = 0, len = value.length; i < len; i++) {
            dataSb.append(Integer.toHexString(value[i] & 0xff));
            dataSb.append(" ");
        }
        ULog.i(TAG, "receive device data:" + dataSb.toString());

        Channel mChannel = null;
        if (uuid.equals(deviceReadNotifyUUIDs[0])) {
            mChannel = Channel.CHANNEL_0;
        } else if (deviceReadNotifyUUIDs.length > 1 && uuid.equals(deviceReadNotifyUUIDs[1])) {
            mChannel = Channel.CHANNEL_1;
        } else if (deviceReadNotifyUUIDs.length > 2 && uuid.equals(deviceReadNotifyUUIDs[2])) {
            mChannel = Channel.CHANNEL_2;
        } else if (deviceReadNotifyUUIDs.length > 3 && uuid.equals(deviceReadNotifyUUIDs[3])) {
            mChannel = Channel.CHANNEL_3;
        } else if (deviceReadNotifyUUIDs.length > 4 && uuid.equals(deviceReadNotifyUUIDs[4])) {
            mChannel = Channel.CHANNEL_4;
        } else if (deviceReadNotifyUUIDs.length > 5 && uuid.equals(deviceReadNotifyUUIDs[5])) {
            mChannel = Channel.CHANNEL_5;
        } else if (deviceReadNotifyUUIDs.length > 6 && uuid.equals(deviceReadNotifyUUIDs[6])) {
            mChannel = Channel.CHANNEL_6;
        } else if (deviceReadNotifyUUIDs.length > 7 && uuid.equals(deviceReadNotifyUUIDs[7])) {
            mChannel = Channel.CHANNEL_7;
        }

        if (mBleMessageAnalyser != null && mChannel != null) {
            mBleMessageAnalyser.onReceiveBleMessage(mChannel, value);
        }
    }

    /**
     * 关闭使能
     */
    private void disabledServiceDestript() {
        if (btService != null) {
            ULog.i(TAG, "do disabledServiceDestript");
            BluetoothGattCharacteristic characteristic = btService.getCharacteristic(UUID.fromString(deviceReadNotifyUUIDs[0]));
            if (characteristic != null && mBluetoothGatt != null) {
                mBluetoothGatt.setCharacteristicNotification(characteristic, true);
                BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(BluetoothUtil.CLIENT_CHARACTERISTIC_CONFIG));
                if (descriptor != null) {
                    ULog.i(TAG, "mBluetoothGatt.writeDescriptor DISABLE_NOTIFICATION_VALUE.");
                    descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
                    mBluetoothGatt.writeDescriptor(descriptor);
                } else {
                    ULog.e(TAG, "descriptor is null.");
                }
                //mBluetoothGatt.readCharacteristic(characteristic);
            }
        }
    }

    Object obj = new Object();
    private long currWriteDataTime = 0;

    /**
     * 写入数据到设备
     *
     * @param bb
     */
    @Override
    public void writeLlsAlertLevel(byte[] bb) {

        synchronized (obj) {
            currMutualTime = System.currentTimeMillis();

            if (!isConnected) {
                ULog.e(TAG, "device not connected, return from writeLlsAlertLevel.");
                return;
            }
            //BluetoothGattService linkLossService = mBluetoothGatt.getService(UUID.fromString(BluetoothUtil.getDeviceServiceUUID(currDeviceType)));
            if (btService == null) {
                ULog.e(TAG, "link loss Alert service not found!");
                return;
            }
            BluetoothGattCharacteristic alertLevel = btService.getCharacteristic(UUID.fromString(BluetoothUtil.getWriteUUID()));

            if (alertLevel == null) {
                ULog.e(TAG, "link loss Alert Level charateristic not found!");
                return;
            }

            if (mBluetoothGatt == null) {
                ULog.e(TAG, "mBluetoothGatt is null");
                return;
            }

            boolean status = false;
            int storedLevel = alertLevel.getWriteType();
            ULog.d(TAG, "storedLevel() - storedLevel=" + storedLevel);
            alertLevel.setValue(bb);
            alertLevel.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
            status = mBluetoothGatt.writeCharacteristic(alertLevel);
            ULog.i(TAG, "----writeLlsAlertLevel-- - status=" + status + ", bb = " + getArrayString(bb));

            if (!status) {

                SystemClock.sleep(100);
                status = mBluetoothGatt.writeCharacteristic(alertLevel);
                ULog.d(TAG, "writeLlsAlertLevel() again - status=" + status);
            }
        }
    }

    //循环监听扫描状态
    protected Runnable scanningThread = new Runnable() {
        public void run() {
            String threadName = Thread.currentThread().getName();
            ULog.i(TAG, "------scanningThread-----run---threadName = " + threadName);

            scanLeDevice(false);

            SystemClock.sleep(1000);

            scanLeDevice(true);
//            if (mHandler != null) {   //zcq删除于201804031810
//                mHandler.postDelayed(this, scanTimeout);
//            }
        }
    };

    /**
     * 监听蓝牙 打开/关闭 状态
     */
    public void setListenerBluetoothState(boolean enable) {
        if (enable) {
            if (!isListeneredBleState) {
                isListeneredBleState = true;
                mContext.registerReceiver(mReceiver, makeBleStateFilter(), "android.permission.BIND_APPWIDGET", new Handler(Looper.myLooper()));
            }
        } else {
            if (isListeneredBleState) {
                isListeneredBleState = false;
                mContext.unregisterReceiver(mReceiver);
            }
        }
    }

    /**
     * 断开当前连接并且退出设备扫描
     */
    public void disConnectAndStopScan() {
        ULog.i(TAG, "------disConnectAndStopScan-----");
        if (mHandler != null) {
            mHandler.removeCallbacks(connectTimeoutThread);
        }
        disConnectDevice();
        stopScanDevice();
    }

    /**
     * 延迟断开连接和关闭设备扫描
     */
    public void delayDisconnectAndStopScan() {
        //停止心跳
        //TODO 需实现该方法
//        ((WeightDataHandle) deviceDataHandler).stopConnHeartbeat();
        cancelBackgroundedNow();
        if (mHandler != null) {
            mHandler.removeCallbacks(dataMutualThread);
            mHandler.post(dataMutualThread);
        }
    }

    /**
     * 取消延迟断开连接和断开设备扫描
     */
    public void cancelDelayDisConnectAndStopScan() {
        ULog.i(TAG, "do cancelDelayDisConnectAndStopScan");
        if (isForeground(mContext)) {
            if (mHandler != null) {
                mHandler.removeCallbacks(dataMutualThread);
            }
        }
    }

    /**
     * 连接超时处理线程
     */
    protected Runnable connectTimeoutThread = new Runnable() {
        @Override
        public void run() {
            ULog.e(TAG, "connect device timeout. do restart device bluetooth.");
            //restartBluetooth();
        }
    };

    /**
     * 监听数据通讯线程
     *
     * @author fenghui
     */
    protected Runnable dataMutualThread = new Runnable() {
        public void run() {
            ULog.i(TAG, "dataMutualThread." + Thread.currentThread().getName());
            if (System.currentTimeMillis() - currMutualTime > BluetoothUtil.getNoMessageTimeout()) {
                ULog.i(TAG, "do delayDisconnectAndStopScan");
                setListenerBluetoothState(false);
                disConnectAndStopScan();


                //此处sleep 1秒给app断开释放连接资源使用
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                ULog.i(TAG, "do releaseDevice for huaweihealth sdk.");
//                SportHealthUtils.getInstance(mContext).releaseDevice();
            } else {
                if (mHandler != null) {
                    mHandler.postDelayed(this, 500);
                }
            }
        }
    };


    public void refreshDeviceCache() {
        if(mBluetoothGatt!=null){
        mBluetoothGatt.disconnect();
        refreshDeviceCache(mBluetoothGatt);
        mBluetoothGatt.close();
        }
    }

    /**
     * Clears the device cache. After uploading new firmware the DFU target will have other services than before.
     *
     * @param gatt the GATT device to be refreshed
     */
    protected void refreshDeviceCache(final BluetoothGatt gatt) {
        /*
         * There is a refresh() method in BluetoothGatt class but for now it's hidden. We will call it using reflections.
		 */
//		try {
//			final Method refresh = gatt.getClass().getMethod("refresh");
//			if (refresh != null) {
//				final boolean success = (Boolean) refresh.invoke(gatt);
//				ULog.i(TAG, "Refreshing result: " + success);
//			}
//		} catch (Exception e) {
//			ULog.e(TAG, "An exception occurred while refreshing device");
//		}
    }

    /**
     * 蓝牙状态监听
     */
    private IntentFilter makeBleStateFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        return filter;
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                isOpenBluetoothing = false;
                if (blueState == BluetoothAdapter.STATE_TURNING_ON) {
                    ULog.i("BLE state receiver", "STATE_TURNING_ON");
                    isOpenBluetoothing = true;
                    if (mBleSatusCallback != null) {
                        mBleSatusCallback.onBleTurningOn();
                    }
                } else if (blueState == BluetoothAdapter.STATE_ON) {
                    ULog.i("BLE state receiver", "STATE_ON");
                    if (mBleSatusCallback != null) {
                        mBleSatusCallback.onBleStateOn();
                    }
//                    deviceDataHandler.getMsgCallBack().onBluetoothOpened();
                 //   startScanDevice();
                } else if (blueState == BluetoothAdapter.STATE_TURNING_OFF) {
                    ULog.i("BLE state receiver", "STATE_TURNING_OFF");
                    if (mBleSatusCallback != null) {
                        mBleSatusCallback.onBleTurningOff();
                    }
                    stopScanDevice();
//                    deviceDataHandler.sendDisconnectBt();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    if (mBluetoothGatt != null) {
                        mBluetoothGatt.disconnect();
                        refreshDeviceCache(mBluetoothGatt);
                        mBluetoothGatt.close();
                    }
                    isConnected = false;
                    mScanning = false;
                    deviceConnectState = BluetoothProfile.STATE_DISCONNECTED;
                } else if (blueState == BluetoothAdapter.STATE_OFF) {
                    ULog.i("BLE state receiver", "STATE_OFF");
                    if (mBleSatusCallback != null) {
                        mBleSatusCallback.onBleStateOff();
                    }
                    //UToast.ShowTask(mContext, "请打开手机蓝牙.");
                    stopScanDevice();
//                    deviceDataHandler.getMsgCallBack().onBluetoothClosed();
                }
            }else if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){//蓝牙扫描结束
                  ULog.i(TAG,"-----蓝牙扫描结束---");
            }
        }
    };


    //app退出到后台相关逻辑处理
    public void delayBackgrounded() {
        ULog.i(TAG, "delayBackgrounded.");
        if (mHandler != null) {
            mHandler.postDelayed(appBackgrounded, 3000);
        }
    }

    public void cancelBackgrounded() {
        ULog.i(TAG, "cancelBackgrounded.");
        if (mHandler != null) {
            mHandler.postDelayed(cancelAppBackgrounded, 2000);
        }
    }

    public void cancelBackgroundedNow() {
        ULog.i(TAG, "cancelBackgrounded now.");
        if (mHandler != null) {
            mHandler.removeCallbacks(appBackgrounded);
        }
    }

    Runnable appBackgrounded = new Runnable() {

        @Override
        public void run() {
            if (!isForeground(mContext)) {
                ULog.i(TAG, "appBackgrounded appBackgrounded.");
                delayDisconnectAndStopScan();
            } else {
                ULog.i(TAG, "appBackgrounded cancel, app is Foreground.");
            }
        }
    };

    Runnable cancelAppBackgrounded = new Runnable() {

        @Override
        public void run() {
            ULog.i(TAG, "appBackgrounded cancelAppBackgrounded.");
            if (mHandler != null) {
                mHandler.removeCallbacks(appBackgrounded);
            }
        }
    };


    //当前应用是否处于前台
    public boolean isForeground(Context context) {
        if (context != null) {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> rtInfos = am.getRunningTasks(1);
            if (rtInfos != null && !rtInfos.isEmpty()) {
                ComponentName cn = rtInfos.get(0).topActivity;
                String currentPackageName = cn.getPackageName();
                if (!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(context.getPackageName())) {
                    return true;
                }
            }
            return false;
        }
        return false;
    }

    public void setOnDeviceConnectedListener(OnDeviceConnectedListener mConnectedListener) {
        this.mConnectedListener = mConnectedListener;
    }

    protected OnDeviceBindFoundListener mDeviceBindFoundListener = new OnDeviceBindFoundListener() {
        @Override
        public void onDeviceBindFound(BluetoothDevice device) {
            ULog.i(TAG, "----startScan----onDeviceBindFound----addr = " + device.getAddress());
            startConnectDevice(device);
        }
    };

    public void setBleSatusCallback(BleSatusCallback mBleSatusCallback) {
        this.mBleSatusCallback = mBleSatusCallback;
    }

    protected StringBuffer sb;

    protected synchronized String getArrayString(byte[] data) {
        if (sb == null) {
            sb = new StringBuffer();
        }
        sb.setLength(0);
        int i = 0;
        while (i < data.length) {
            sb.append(Integer.toHexString(data[i] & 0xff)).append(" ");
            i++;
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    /**
     * 释放资源的方法
     */
    public void release() {
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }

        mConnectedListener = null;
        mBleSatusCallback = null;
        mScanResultCallback = null;
        mConnectCallback = null;
        mBleMessageAnalyser = null;


        //断开链接,置空
        if (mBluetoothGatt != null) {
            mBluetoothGatt.disconnect();
            mBluetoothGatt.close();
            mBluetoothGatt = null;
        }

        //释放资源
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter = null;
        }

        instance = null;

    }

}